package com.atguigu.lease.admin.service.impl;

import com.atguigu.lease.admin.service.SystemLoginService;
import com.atguigu.lease.admin.service.SystemUserService;
import com.atguigu.lease.common.util.JwtUtil;
import com.atguigu.lease.model.bean.SystemUser;
import com.atguigu.lease.model.dto.LoginSubmitDto;
import com.atguigu.lease.model.vo.CaptchaVo;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.wf.captcha.GifCaptcha;
import io.jsonwebtoken.CompressionCodecs;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.UUID;

@Service
public class SystemLoginServiceImpl implements SystemLoginService {
    @Autowired
    SystemUserService systemUserService;
    // 只要项目引入了springboot redis 启动器+ 配置了redis连接地址端口号+服务端启动了redis+关闭了防火墙
    //  项目启动时 就会创建redisTemplate对象注入到IOC容器中
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Override
    public CaptchaVo getCaptcha() {
        //1、生成验证码
        GifCaptcha gifCaptcha = new GifCaptcha(100, 40, 4);
        //2、将验证码值 存到redis中,并分配唯一的键
        String uuid = UUID.randomUUID().toString().replace("-" , "");
        stringRedisTemplate.opsForValue()
                .set("stgy:admin:"+uuid, gifCaptcha.text());
        //3、封装vo对象响应
        CaptchaVo captchaVo = new CaptchaVo();
        captchaVo.setKey(uuid);
        captchaVo.setImage(gifCaptcha.toBase64());
        return captchaVo;
    }

    @Override
    public String login(LoginSubmitDto loginSubmitDto) {
        //1、校验登录参数:
        //2、校验登录验证码： 必须和redis中的一样
        // 获取前端提交的验证码
        String code = loginSubmitDto.getCaptchaCode();
        // 获取redis中缓存的验证码
        String captchaKey = loginSubmitDto.getCaptchaKey();
        String key = "stgy:admin:" + captchaKey;
        String redisCachedCode = stringRedisTemplate.opsForValue().get(key);
        //判断redis的验证码 和前端提交的是否一致
        if(StringUtils.isEmpty(redisCachedCode) || !code.equalsIgnoreCase(redisCachedCode) ) {
            //验证码错误
            throw new RuntimeException("验证码错误");
        }
        //验证码正确
        //3、删除缓存的验证码： 避免表单重复提交
        stringRedisTemplate.delete(key);

        //4、处理登录业务：
        // 4.1 根据账号查询数据库中的用户信息
        SystemUser systemUser = systemUserService.getOne(Wrappers.lambdaQuery(SystemUser.class)
                .eq(SystemUser::getUsername, loginSubmitDto.getUsername()));
        if(systemUser == null) {
            throw new RuntimeException("账号不存在");
        }
        // 4.2 使用提交的密码加密 和数据库查询到的密码比较
        String encodedPwd = DigestUtils.md5DigestAsHex(loginSubmitDto.getPassword().getBytes());
        if(!systemUser.getPassword().equals(encodedPwd)) {
            throw new RuntimeException("密码错误");
        }

        // 4.3 判断用户状态 是不是可用
        if(systemUser.getStatus().intValue()!=1){
            throw new RuntimeException("账号被禁用");
        }
        //5、创建jwt 返回
//        String secretKey = "1234567890qazwsxedcrfvtgbyhnujmik2213wrewrw4234234235werwrewtesdfsfsfsafsdfdsafsa";
//        String jwt = Jwts.builder()
//                //头
//                .setHeaderParam("typ", "JWT")
//                .setHeaderParam("alg", "HS256")
//                //载荷
//                .setExpiration(new Date(System.currentTimeMillis() + 7 * 24 * 60 * 60 * 1000))
//                .claim("userId", systemUser.getId())//登录成功的用户id
//                .claim("username", systemUser.getName()) //登录成功的用户账号
//                .claim("avatarUrl" , systemUser.getAvatarUrl()) //登录成功用户的头像
//                .compressWith(CompressionCodecs.GZIP) //jwt字符串响应给前端时 压缩处理，减少带宽的占用，提高传输效率 但是占用了额外的CPU资源
//                .signWith(SignatureAlgorithm.HS256, secretKey)
//                .compact();
        return JwtUtil.createJwt(systemUser.getId() , systemUser.getName() , systemUser.getAvatarUrl());
    }
}
